'''
窗口显示图片，画矩形框，可鼠标调整矩形框 20240626
'''

import sys
import traceback

import cv2
import numpy
import numpy as np
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel
from PyQt5.QtCore import Qt, QRectF, QPointF, QLineF
from PyQt5.QtGui import QPainter, QPixmap, QImage, QPen, QColor, QFont, QCursor

import yaml
# from log import saved_algo_param_dict
from defconfig import global_dict_param



def array2pix(image, ismask=False):
    if len(image.shape) == 2:
        image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGRA)

    if image.shape[2] == 1:
        image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGRA)

    if image.shape[2] == 3:
        #image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2BGRA)
    #show1 = cv2.resize(image, (640, 480))
    if ismask:
        #image[:,:,3] = image[:,:,2]
        pass

    show1 = image
    #QtImg = QImage(show1.data, show1.shape[1], show1.shape[0], QImage.Format_BGR888)
    QtImg = QImage(
        show1.data, show1.shape[1], show1.shape[0], QImage.Format_ARGB32)
    pixmap = QPixmap(QtImg)
    return pixmap

def read_yaml(file_path):
    with open(file_path, 'r') as file:
        config = yaml.safe_load(file)
    return config


def write_yaml(data, file_path):
    with open(file_path, 'w') as file:
        yaml.safe_dump(data, file)
class ImageWithResizableBox(QWidget):
    def __init__(self, imagePath, threshold_list=[100,100]):
        super().__init__()
        self.imagePath = imagePath
        if isinstance(imagePath, numpy.ndarray):
            # self.pixmap = numpy_array_to_qpixmap(imagePath)
            self.pixmap = array2pix(imagePath)
        else:
            self.pixmap = QPixmap(imagePath)
        self.scale = 0.4
        self.pixmap = self.pixmap.scaled(int(self.pixmap.width()*self.scale), int(self.pixmap.height()*self.scale), Qt.KeepAspectRatio, Qt.SmoothTransformation)


        # self.rect2 = QRectF(590, 476, 100, 0)  # 初始矩形框位置和大小
        # self.line = QLineF(50, 100)  #
        self.handle_size = 10
        self.dragging = False
        self.dragging_listrect_listconer = [[False, False, False, False]] # [[rect1],[rect2]]
        self.drag_start_pos = QPointF()
        self.dragged_handle = None

        self.initUI()
        # self.threshold_list = threshold_list # 要设置的阈值

        # self.param_path = r'D:\code\git\zxc\fuba_\project_format_fubatianxian\config/param.yaml'
        self.step8_param_dict = {'height': 100, 'x1y1': [100,100] } # h, x1,y1
        try:
            self.param_path = 'config/param.yaml'
            self.step8_param_dict = read_yaml(self.param_path)['step8']
        except:
            try:
                self.param_path = r'D:\code\git\zxc\huoni\0311\project_honey\config\param.yaml'
                self.step8_param_dict = read_yaml(self.param_path)['step8']
            except:
                print(traceback.format_exc())

        self.rect_list = [QRectF(self.step8_param_dict['x1y1'][0], self.step8_param_dict['x1y1'][1], 0, int(self.step8_param_dict['height']*self.scale))] # 初始矩形框位置和大小；卡扣上，卡扣下

    def initUI(self):
        # self.layout = QVBoxLayout(self)
        # self.label = QLabel("双击图片加载，拖动矩形框的角来调整大小", self)
        # self.layout.addWidget(self.label)
        self.setWindowTitle('修改步骤8满盒检测阈值')
        self.resize(self.pixmap.width(), self.pixmap.height())  # 调整窗口大小以适应图片
        pass

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.drawPixmap(0, 0, self.pixmap)

        painter.setRenderHint(QPainter.Antialiasing)
        # pen = QPen(QColor(255, 0, 0), 2)
        # painter.setPen(pen)


        # 绘制矩形，矩形边角方框
        for ind, rect in enumerate(self.rect_list):
            if ind == 0: # 卡扣上
                painter.setPen(QPen(QColor(0, 255, 255), 2))
            else:
                painter.setPen(QPen(QColor(0, 255, 0), 2))
            painter.drawRect(rect)
            for corner in [(rect.topLeft(), 1), (rect.topRight(), 2),
                           (rect.bottomRight(), 3), (rect.bottomLeft(), 4)]:
                painter.drawRect(corner[0].x() - self.handle_size // 2,
                                 corner[0].y() - self.handle_size // 2,
                                 self.handle_size, self.handle_size)

        # 设置字体
        font = QFont('Arial', 24)
        painter.setFont(font)

        painter.setPen(QPen(QColor(0, 255, 255), 2))
        # painter.drawText(50, 100, f'卡扣上:{self.rect_list[0].width()}') # 文字左下角的位置 (x, y)
        painter.drawText(1000, 100, f"高度阈值:{self.step8_param_dict['height']}")  # 文字左下角的位置 (x, y)
        # painter.setPen(QPen(QColor(0, 255, 0), 2))
        # painter.drawText(800, 150, f'卡扣下阈值:{self.threshold_list[1]}')  # 文字左下角的位置 (x, y)

    def mouseDoubleClickEvent(self, event):
        self.update()

    def mousePressEvent(self, event): # 鼠标按下
        try:
            print('xxxx')
            if event.button() == Qt.LeftButton:
                for rect_ind, rect in enumerate(self.rect_list):
                    self.rect = rect
                    for corner, handle_index in [(self.rect.topLeft(), 1), (self.rect.topRight(), 2),
                                                 (self.rect.bottomRight(), 3), (self.rect.bottomLeft(), 4)]:


                        print(event.globalPos()) # 全局坐标
                        print(event.pos())  # 局部坐标
                        print((event.globalPos() - self.mapToGlobal(corner.toPoint())).manhattanLength())
                        if (event.globalPos() - self.mapToGlobal(corner.toPoint())).manhattanLength() <= self.handle_size / 2:

                            # self.dragging = True # 拖动tag
                            # self.dragged_handle = handle_index
                            # self.drag_start_pos = event.globalPos() - self.mapToGlobal(corner.toPoint())
                            self.dragging_listrect_listconer[rect_ind][handle_index-1] = True  # 拖动tag, 矩形被点击的角
                            # 改变鼠标形状为“选中”或手势指示的光标
                            hand_cursor = QCursor(Qt.PointingHandCursor)
                            self.setCursor(hand_cursor)
                            # break
                        else:
                            self.dragging_listrect_listconer[rect_ind][handle_index - 1] = False

                # else:
                #     # 如果没有点击到手柄，尝试加载图片
                #     if not self.pixmap.isNull():
                #         return
                #     self.imagePath = "your_image_path_here.png"  # 替换为你的图片路径
                #     self.pixmap = QPixmap(self.imagePath)
                #     self.update()
        except:
            print(traceback.format_exc())


    def mouseMoveEvent(self, event): # 鼠标移动, 记录阈值
        try:
            print('mouseMoveEvent')

            fun_list = [[self.rect_list[0].setTopLeft, self.rect_list[0].setTopRight, self.rect_list[0].setBottomRight, self.rect_list[0].setBottomLeft],]
            global_pos = event.globalPos()
            for rect_ind, dragging_listconer in enumerate(self.dragging_listrect_listconer):
                # wid = self.rect_list[rect_ind].width()
                hei = self.rect_list[rect_ind].height()
                if hei == 0:
                    print(f'矩形高度为0')
                    # if coner_ind in (2, 3):  # 如果矩形宽度为0，只拖右上角，右下角
                    #     is_dragging = False
                    # dragging_listconer[0]=False
                    # dragging_listconer[3]=False
                    dragging_listconer[2]=False # 右下角
                    dragging_listconer[3]=False # 左下角
                for coner_ind, is_dragging in enumerate(dragging_listconer):

                    if is_dragging:
                        fun_list[rect_ind][coner_ind](self.mapFromGlobal(global_pos)) # 移动矩形角点
                        # self.threshold_list[rect_ind] = self.rect_list[rect_ind].width()/self.scale
                        self.step8_param_dict['height'] = self.rect_list[rect_ind].height() / self.scale
                        self.step8_param_dict['x1y1'] = [self.rect_list[rect_ind].topLeft().x(),self.rect_list[rect_ind].topLeft().y()]

                # self.paintText()

            self.update()  # 执行paintEvent()
        except:
            print(traceback.format_exc())

    def mouseReleaseEvent(self, event): # 鼠标释放
        try:
            print('mouseReleaseEvent')
            param_dict = read_yaml(self.param_path)
            param_dict['step8'] = self.step8_param_dict
            write_yaml(param_dict, self.param_path)

            global_dict_param['step8']['height'] = param_dict['step8']['height'] # 不重启生效

            # write_yaml(param_dict['step5'], self.param_path + '_step5.yaml')
            # saved_algo_param_dict['step5'] = self.threshold_list
            self.setCursor(QCursor(Qt.ArrowCursor)) # 默认箭头

            self.dragging = False
            self.dragged_handle = None
            self.update()
        except:
            print(traceback.format_exc())

    def closeEvent(self, event):
        # saved_algo_param_dict['step5'] = []
        pass

if __name__ == "__main__":
    app = QApplication(sys.argv)
    widget = ImageWithResizableBox(r"D:\data\231207huoni\trainV8Seg_full_box\add_imgs\20240801\img_8_20240513_173407_006_jc_full_box_NG_img(1).jpg")  # 替换为初始图片路径
    widget.resize(widget.pixmap.width(), widget.pixmap.height())  # 调整窗口大小以适应图片
    widget.show()
    sys.exit(app.exec_())
